%  This file is part of Erlywog.

%  Erlywog is free software: you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation, either version 3 of the License, or
%  (at your option) any later version.

%  Erlywog is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.

%  You should have received a copy of the GNU General Public License
%  along with Erlywog.  If not, see <http://www.gnu.org/licenses/>.

%  Copyright Jasm Sison 2009

-module(blog_controller).
-export(
  [
    index/1
    , entry/1
    , entry/2
    , latest/1
    , archives/3
    , categories/2
    , projects/2
    , simple_entry/2
    , complex_entry/2
%     , commentifier/2 %% TODO - remove
  ]).

%
% Macros
%
-define(MAX_BLOG_ENTRIES, 4).
-define(MAX_FULL_SHOW_ENTRIES, 2).
-define(MAX_ARBITRARY_NUMBER, 10000000).

index(A) ->
  latest(A).

entry(A) ->
  latest(A).

entry(A, Id) ->
  Entry = entry:find_first({id,'=',Id}),
  case Entry of
    undefined ->
      {data, <<"Sorry, no such entry found">>}
    ;_ ->
      Ewcs = [
        {ewc, blog, complex_entry, [A, Entry]}
        , {ewc, commentizer, show_comments, [A, entry:id(Entry)]}
      ]
      , PhasedVars = [
        {html_header_title, entry:title(Entry)},
        {html_header, {ewc, commentizer, javascript_deps, [A]}},
	{html_header, {ewc, commentizer, header, [A]}}
      ]
      , blog_util:phased_response(Ewcs, PhasedVars)
  end.

latest(A) ->
  Entries = entry:find({published,'is not',null},[{order_by, {published,desc}}, {limit, ?MAX_BLOG_ENTRIES}])
  , [{ewc, blog, simple_entry, [A, Entry]} || Entry <- Entries].

%% Show all the entries matching this 'project'
projects (A, Project) ->
  Ids = [ entry_project:entry_id(EP) || EP <- entry_project:find({project_name,'=',Project}) ],
  Entries = [ entry:find_first({id,'=',Id}) || Id <- Ids ],
  case Entries of
    [] -> 
      {data, no_such_project}
    ;_ -> 
      [{ewc, blog, simple_entry, [A, Entry]} || Entry <- Entries]
  end.
  
%% Show all the entries matching this 'category'
categories(A, Category) ->
  Ids = [ entry_category:entry_id(EC) || EC <- entry_category:find({category_name,'=',Category}) ],
  Entries = [ entry:find_first({id,'=',Id}) || Id <- Ids ],
  case Entries of
    [] -> 
      {data, no_such_category}
    ;_ -> 
      [{ewc, blog, simple_entry, [A, Entry]} || Entry <- Entries]
  end.

%% Show all the entries published in this 'archive'
archives(A, Year, Month) ->
  Archives = archive:find({{year,'=',list_to_integer(Year)},'and',{month,'=',list_to_integer(Month)}}),
  Ids = [ archive:entry_id(Arch) || Arch <- Archives ],
  Entries_ = [ entry:find_first({id,'=',Id}) || Id <- Ids ],
  Entries = [ Entry || Entry <- Entries_, Entry =/= undefined ], %% filtered for "undefined"
  case Entries of
    [] -> 
      {data, no_such_archive}
    ;_ -> 
      [ {ewc, blog, simple_entry, [A, Entry]} || Entry <- Entries ]
  end.

%% Munch blog entries from the database
simple_entry (A, Entry) ->
  Get_ =
    fun (Field) ->
      erlydb_base:field_to_iolist(entry:Field(Entry))
    end
  , Get = fun (Field) -> entry:Field(Entry) end
  , Id = Get_(id)
  , {data
      , {
          _Id = Id
        , _Title = Get(title)
        , _Author = Get(blogger_name)
        , _Published = Get_(published)
        , _Body = Get(body) %% introbody, not whole, decide later on
        , _Categories = get_entry_categories(Entry)
        , _Projects = get_entry_projects(Entry)
        , _CommentsLink = [[erlyweb:get_app_root(A), <<"blog/entry/">>], Id, <<"#comments">>] %% TODO - test erlyweb:get_app_root(A)
	, _CommentCount = get_number_comments_of_entry(Get(id))
%         , _CommentsLink = [<<"/blog/entry/">>, Id, <<"#comments">>]
    }
  }.

complex_entry (_A, Entry) ->
  Get_ =
    fun (Field) ->
      erlydb_base:field_to_iolist(entry:Field(Entry))
    end
  , Get = fun (Field) -> entry:Field(Entry) end
  , {data
        , {
          _Id = Get_(id)
        , _Title = Get(title)
        , _Author = Get(blogger_name)
        , _Published = Get_(published)
        , _Body = Get(body) %% introbody, not whole, decide later on
        , _Categories = get_entry_categories(Entry)
        , _Projects = get_entry_projects(Entry)
        }
  }.
  
%% Handle the data munching of categories per entry
get_entry_categories (Entry) ->
  Cs = entry_category:find({entry_id,'=',entry:id(Entry)}),
  case Cs of
    [] -> no_categories
%    ;_ -> [ {[erlyweb:get_app_root(A), <<"blog/categories/">>], entry_category:category_name(C)} || C <- Cs ] %% TODO - test erlyweb:get_app_root(A)
    ;_ -> [ {<<"/blog/categories/">>, entry_category:category_name(C)} || C <- Cs ]
  end.

%% Handle the data munching of projects per entry
get_entry_projects (Entry) ->
  Ps = entry_project:find({entry_id,'=',entry:id(Entry)}),
  case Ps of
    [] -> no_projects
%    ;_ -> [ {[erlyweb:get_app_root(A), <<"blog/projects/">>], entry_project:project_name(P)} || P <- Ps ] %% TODO - test erlyweb:get_app_root(A)
    ;_ -> [ {<<"/blog/projects/">>, entry_project:project_name(P)} || P <- Ps ]
  end.

get_number_comments_of_entry(Id) ->
  integer_to_list(comment:count('*', {entry_id,'=',Id})).
